﻿using NAppUpdate.Framework;
using NAppUpdate.Framework.Common;
using Futajma.MigrationStudio.SharePointPersistance;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Futajma.MigrationStudio.ApplicationUpdate
{
    public enum UpdateState
    {
        Error,
        Prepared
    }
    public delegate void PrepareUpdatesCompleted(UpdateState updateState);

    public class ApplicationUpdater
    {
        public event PrepareUpdatesCompleted OnPrepareUpdatesCompleted;
        public bool CheckForUpdates(TargetAudience targetAudience, string currentVersion)
        {
            var updateEnabledConfig = ConfigurationManager.AppSettings["EnableAutoUpdates"];

            UpdateManager.Instance.UpdateSource = new SharePoint2010UpdateSource(targetAudience, currentVersion);

            var updateEnabled = bool.Parse(updateEnabledConfig);

            if (updateEnabled == false)
            {
                return false;
            }

            // Get a local pointer to the UpdateManager instance
            UpdateManager updManager = UpdateManager.Instance;

            // Only check for updates if we haven't done so already
            if (updManager.State != UpdateManager.UpdateProcessState.NotChecked)
            {
                return false;
            }

            //try
            //{
            // Check for updates - returns true if relevant updates are found (after processing all the tasks and
            // conditions)
            // Throws exceptions in case of bad arguments or unexpected results
            updManager.CheckForUpdates();
            //}
            //catch (Exception ex)
            //{
            //if (ex is NAppUpdateException)
            //{
            //    // This indicates a feed or network error; ex will contain all the info necessary
            //    // to deal with that
            //}

            //    return false;
            //}

            if (updManager.UpdatesAvailable != 0)
            {
                return true;
            }

            return false;
        }

        public bool CheckForUpdates(TargetAudience targetAudience)
        {
            return CheckForUpdates(targetAudience, AssemblyVersion);
        }

        public string AssemblyVersion
        {
            get
            {
                return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
            }
        }

        public bool PrepareForUpdate()
        {
            if (UpdateManager.Instance.State != UpdateManager.UpdateProcessState.Checked)
            {
                return false;
            }

            if (UpdateManager.Instance.UpdatesAvailable == 0)
            {
                return false;
            }
            UpdateManager.Instance.BeginPrepareUpdates(onPrepareUpdatesCompleted, null);
            return true;
        }

        private void onPrepareUpdatesCompleted(IAsyncResult asyncResult)
        {
            try
            {
                ((UpdateProcessAsyncResult)asyncResult).EndInvoke();
                if (OnPrepareUpdatesCompleted != null) OnPrepareUpdatesCompleted(UpdateState.Prepared);
            }
            catch (Exception ex)
            {
                if (OnPrepareUpdatesCompleted != null) OnPrepareUpdatesCompleted(UpdateState.Error);
                //MessageBox.Show(string.Format("Updates preperation failed. Check the feed and try again.{0}{1}", Environment.NewLine, ex));                
            }

        }

        public void InstallUpdates()
        {

            // Get a local pointer to the UpdateManager instance
            UpdateManager updManager = UpdateManager.Instance;

            // This is a synchronous method by design, make sure to save all user work before calling
            // it as it might restart your application

#if DEBUG
            updManager.ApplyUpdates(false, true, true);
#else
            updManager.ApplyUpdates(false, true, false);
#endif

        }

        public void UploadInstallationReports()
        {
            var path = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);

            var filename = Path.Combine(path, "NauUpdate.log");

            if (File.Exists(filename))
            {
                SharePoint2010ApplicationConfiguration.UploadLogFile(filename);
                File.Delete(filename);
            }
        }

    }
}
